using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Dragoon.BreakIt.View
{
    class BackgroundRenderer : Microsoft.Xna.Framework.DrawableGameComponent
    {
        readonly Rectangle _topPipeSrc;
        readonly Rectangle _topLeftPipeSrc;
        readonly Rectangle _leftPipeSrc;
        readonly Rectangle _topRightPipeSrc;
        readonly Rectangle _rightPipeSrc;
        readonly Rectangle _leftInnerSrc;
        readonly Rectangle _topLeftInnerSrc;
        readonly Rectangle _backgroundSrc;
        readonly Point _tileCounts;
        readonly Point _targetTileSize;
        readonly Rectangle _offsetTarget;
        private readonly Rectangle InnerArea;
        public readonly Rectangle InnerRect;
        private readonly TileMap Tiles;

        private SpriteBatch _drawBatch;

        public BackgroundRenderer(
            Game game,
            Rectangle playArea, 
            int tileCountForX, 
            int tileCountForY,
            TileMap tiles)
            : base(game)
        {
            System.Diagnostics.Debug.Assert(tiles != null);
            Tiles = tiles;
            _targetTileSize = new Point(playArea.Width / tileCountForX, playArea.Height / tileCountForY);
            _tileCounts = new Point(tileCountForX, tileCountForY);
            _offsetTarget = new Rectangle(
                playArea.Left, playArea.Top, 
                _targetTileSize.X, _targetTileSize.Y);

            InnerArea = new Rectangle(_offsetTarget.Right, _offsetTarget.Bottom,
                (_tileCounts.X - 1) * _targetTileSize.X, (_tileCounts.Y - 1) * _targetTileSize.Y);
            InnerRect = new Rectangle(
                _offsetTarget.Right, 
                _offsetTarget.Bottom + Tiles.Texels(12,_targetTileSize.Y), // cater for the pipe in the tile
                (_tileCounts.X - 2) * _targetTileSize.X, 
                (_tileCounts.Y - 2) * _targetTileSize.Y);
            /*
            InnerArea.Offset((InnerArea.Width - playArea.Width) / 2,
                (InnerArea.Height - playArea.Height) / 2); */

            _topPipeSrc = Tiles.GetBlock(15,2);
            _topLeftPipeSrc = Tiles.GetBlock(13, 1);
            _topLeftInnerSrc = Tiles.GetBlock(14, 1);
            _leftPipeSrc = Tiles.GetBlock(13, 2);
            _leftInnerSrc = Tiles.GetBlock(14, 2);
            _topRightPipeSrc = Tiles.GetBlock(17, 1);
            _rightPipeSrc = Tiles.GetBlock(17, 2);
            _backgroundSrc = Tiles.GetBlock(6, 0);
        }


        private Rectangle at(int x, int y)
        {
            Rectangle r = _offsetTarget;
            r.X = x * _targetTileSize.X;
            r.Y = y * _targetTileSize.Y;
            return r;        
        }


        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            _drawBatch = new SpriteBatch(this.GraphicsDevice);
        }

        public override void Draw(GameTime gameTime)
        {
            _drawBatch.Begin();
            Texture2D sourceImage = Tiles.Texture;
            // draw the field background

            for (int i = 0; i < _tileCounts.X; i++)
            {
                for (int j = 0; j < _tileCounts.Y; j++)
                    _drawBatch.Draw(sourceImage,
                        at(i, j),
                        _backgroundSrc,
                        Color.White);
            }
            // draw corners
            _drawBatch.Draw(sourceImage, at(0, 1), _topLeftPipeSrc, Color.White);
            _drawBatch.Draw(sourceImage, at(1, 1), _topLeftInnerSrc, Color.White);
            _drawBatch.Draw(sourceImage, at(_tileCounts.X - 1, 1), _topRightPipeSrc, Color.White);
            // draw top lines and inner
            Rectangle r = at(2, 1);
            Rectangle d;
            for (; r.X < InnerArea.Right - _targetTileSize.X; r.X += _targetTileSize.X)
            {
                _drawBatch.Draw(sourceImage, r, _topPipeSrc, Color.White);
            }
            // draw side lines
            int RIGHT = _targetTileSize.X * (_tileCounts.X - 1);
            d = at(0, 2);
            for (;
                d.Y < InnerArea.Bottom;
                d.Y += _targetTileSize.Y)
            {
                _drawBatch.Draw(sourceImage, d, _leftPipeSrc, Color.White);
                d.X += _targetTileSize.X;
                _drawBatch.Draw(sourceImage, d, _leftInnerSrc, Color.White);
                d.X += RIGHT - _targetTileSize.X;
                _drawBatch.Draw(sourceImage, d, _rightPipeSrc, Color.White);
                d.X = _offsetTarget.X;
            }
            _drawBatch.End();
        }

    }
}
